﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ex03.VehicalsObjectModel
{
    public abstract class Vehical
    {
        // Members
        private string m_LicenseNumber;
        protected List<VehicalWheel> m_Wheels;
        protected VehicalEnergySystem m_EnergySystem;

        // Ctor

        /// <summary>
        /// Initializes the abstract vehical
        /// </summary>
        /// <param name="i_LicenseNumber">The license number of the vehical</param>
        /// <param name="i_EnergySystem">The energy system of the vehical</param>
        /// <exception cref="FormatException">When the license number is malformed</exception>
        protected Vehical(string i_LicenseNumber, VehicalEnergySystem i_EnergySystem)
        {
            // Check Validation
            if (isValidLicenseNumber(i_LicenseNumber))
            {
                m_LicenseNumber = i_LicenseNumber;
                m_EnergySystem = i_EnergySystem;

                // Init the wheels
                m_Wheels = new List<VehicalWheel>(k_NumOfWheels);
                for (int currentWheel = 0; currentWheel < k_NumOfWheels; currentWheel++)
                {
                    m_Wheels.Add(new VehicalWheel(k_DefaultWheelsPSI));
                }
            }
        }

        // Properties

        /// <summary>
        /// Gets a list of the vehicals wheels
        /// </summary>
        public List<VehicalWheel> Wheels
        {
            get 
            { 
                return m_Wheels; 
            }
        }

        /// <summary>
        /// Gets the license number of the vehical
        /// </summary>
        public string LicenseNumber
        {
            get 
            { 
                return m_LicenseNumber; 
            }
        }

        /// <summary>
        /// Gets the percentage of currently available energy
        /// </summary>
        public int CurrentEnregyPercent
        {
            get
            {
                return m_EnergySystem.CurrentEnergyPercent;
            }
        }

        /// <summary>
        /// Gets the number of wheels on the vehical
        /// </summary>
        protected abstract int k_NumOfWheels
        {
            get;
        }

        /// <summary>
        /// Gets the default PSI for the wheels on the vehical
        /// </summary>
        protected abstract float k_DefaultWheelsPSI
        {
            get;
        }

        public VehicalEnergySystem VehicalEnergySystem
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public VehicalWheel VehicalWheel
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        // Methods

        /// <summary>
        /// Checks validation of a license number
        /// </summary>
        /// <param name="i_LicenseNumber">The license number to check</param>
        /// <returns>True if the license number is valid</returns>
        /// <exception cref="FormatException">If the license number is not of a valid form</exception>
        public static bool isValidLicenseNumber(string i_LicenseNumber)
        {
            const int v_AllowedSegments = 3;
            const char v_SegmentsSeparator = '-';
            int[] v_SegmentSizes = new int[] { 2, 3, 2 };
            string[] numberSegments = i_LicenseNumber.Split(v_SegmentsSeparator);
            bool isValidLicenseNumber = false;

            // Check if the license number is not correctly segmented
            if (numberSegments.Length != v_AllowedSegments)
            {
                throw new FormatException("Invliad license number");
            }
            else
            {
                // Check the size if the segments, and their content
                for (int currentSegment = 0; currentSegment < v_AllowedSegments; currentSegment++)
                {
                    if (numberSegments[currentSegment].Length == v_SegmentSizes[currentSegment])
                    {
                        int.Parse(numberSegments[currentSegment]);
                    }
                }

                // All segments are of the correct size, and no format exception was throws
                // So its all numbers
                isValidLicenseNumber = true;
            }

            return isValidLicenseNumber;
        }

        /// <summary>
        /// Returns the type name of the vehical, without namespaces
        /// </summary>
        /// <returns></returns>
        public string GetTypeName()
        {
            string[] namespaceParts = this.GetType().ToString().Split('.');
            return namespaceParts[namespaceParts.Length - 1];
        }
    }
}
